package com.boarsoft.boar.batch.action;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.boarsoft.boar.base.service.AppInstService;
import com.boarsoft.boar.batch.bean.BatchAppStat;
import com.boarsoft.boar.batch.service.BatchBrokerService;
import com.boarsoft.boar.common.Constants;
import com.boarsoft.boar.entity.AppInst;
import com.boarsoft.common.Authorized;
import com.boarsoft.common.Util;
import com.boarsoft.common.action.PageAction;
import com.boarsoft.common.dao.PagedResult;
import com.boarsoft.common.util.JsonUtil;

@SuppressWarnings("serial")
@Component
@Scope("prototype")
@ParentPackage("default-package")
@Namespace(value = "/app")
public class BatchAppAction extends PageAction implements ApplicationContextAware {

	@Autowired(required = false)
	private AppInstService appInstService;

	/** */
	private ApplicationContext applicationContext;

	/** */
	private String addr;
	/** */
	private String catalog;
	/** */
	private String appId;
	/** */
	private String env;
	/** BatchBrokderService bean name */
	private String broker;

	@SuppressWarnings("unchecked")
	@Action("list")
	@Authorized(code = "batch.app.list")
	public void list() {
		if (Util.strIsEmpty(broker)) {
			writeReply(Constants.ERROR_INVALID, "broker");
			return;
		}
		if (Util.strIsEmpty(catalog)) {
			writeReply(Constants.ERROR_INVALID, "catalog");
			return;
		}
		if (!applicationContext.containsBean(broker)) {
			writeReply(Constants.ERROR_NOTFOUND, "broker");
			return;
		}
		// 获取对应的BatchBrokerService
		BatchBrokerService bbs = applicationContext.getBean(broker, BatchBrokerService.class);
		// 广播调用所有批量实例
		Map<String, Object> rm = (Map<String, Object>) bbs.stat();
		for (String k : rm.keySet()) {
			Object o = rm.get(k);
			BatchAppStat s = null;
			if (o == null) {
				log.error("Can not get stat from {}", k);
				s = new BatchAppStat(catalog, k, AppInst.STATUS_UNKNOWN);
			} else if (o instanceof Throwable) {
				log.error("Error on get stat from {}", k, o);
				s = new BatchAppStat(catalog, k, AppInst.STATUS_FAILED);
			}
			if (o instanceof BatchAppStat) {
				s = (BatchAppStat) o;
				s.setStatus(AppInst.STATUS_RUNNING);
			}
			rm.put(k, s);
		}
		// 遍历所有指定应用的实例
		if (appInstService != null) {
			List<AppInst> lt = appInstService.list(appId, env, null);
			for (AppInst a : lt) {
				String k = a.getAddr();
				if (rm.containsKey(k)) {
					continue;
				}
				rm.put(k, new BatchAppStat(catalog, k, AppInst.STATUS_UNKNOWN));
			}
		}
		List<BatchAppStat> lt = new ArrayList<BatchAppStat>();
		for (Object s : rm.values()) {
			lt.add((BatchAppStat) s);
		}
		PagedResult<BatchAppStat> pr = //
				new PagedResult<BatchAppStat>(lt.size(), lt, 1, pageSize);
		writeReply(true, JsonUtil.from(pr));
	}

	@Action("delete")
	@Authorized(code = "batch.app.delete")
	public void delete() {
		if (Util.strIsEmpty(addr)) {
			writeReply(Constants.ERROR_INVALID, "addr");
			return;
		}
		if (appInstService == null) {
			writeReply(Constants.ERROR_UNSUPPORTED);
			return;
		}
		try {
			appInstService.delete(addr);
			writeReply();
		} catch (Exception e) {
			log.error("Error on delete batch inst", e);
			writeReply(Constants.ERROR_UNKNOWN);
		}
	}

	public String getAddr() {
		return addr;
	}

	public void setAddr(String addr) {
		this.addr = addr;
	}

	public String getCatalog() {
		return catalog;
	}

	public void setCatalog(String catalog) {
		this.catalog = catalog;
	}

	public String getEnv() {
		return env;
	}

	public void setEnv(String env) {
		this.env = env;
	}

	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}

	public String getAppId() {
		return appId;
	}

	public void setAppId(String appId) {
		this.appId = appId;
	}

	public String getBroker() {
		return broker;
	}

	public void setBroker(String broker) {
		this.broker = broker;
	}

}
